﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
using VizConnectC;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using Microsoft.Win32;

namespace DataToViz
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
        /// <summary>
        /// 得到当前活动的窗口
        /// </summary>
        /// <returns></returns>
        private const int SW_HIDE = 0;
        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImport("User32.dll")]
        public static extern IntPtr FindWindow(string ClassN, string WindN);
        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
         public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
        public Form1()
        {
            InitializeComponent();
            confilefile = new XmlDocument();
            confilefile.Load(Application.StartupPath + "\\confige.xml");
        }
        //网络监听
        NetProcess process;
        //使用测试类
        //ServerTest serverTest;

        Process pro = null;

        Thread thTimer = null;

        public static Process backworkPro = null;
        public static ProcessReturnFromCmdHandler processReturnFromCmdEvent;


        //VIZ打开后多长时间载入场景
        public static int runsleep = 0;
        public static int loadscenesleep = 0;
        public static int recivesleep = 0;
        public static string scene = ""; 
        public static string FrontSceneName = ""; 
        public static string ghpath = "";
        public static string usbserverip = "";
        public static string usbsharedport = "";

        public static Thread thread = null;

        XmlDocument confilefile;

        //public static Form1 from1Instance = null;
        //public delegate void recivecommand(string command);
        //处理 VIZ 事件
        //public event recivecommand ReciveCommand;

        void Form1FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseVIZ();
            e.Cancel = false;
        }
        public static string filepath = "";
        /// <summary>
        /// 读取了confige.xml配置文件
        /// 初始化了网络处理类
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //from1Instance = this;
            this.notifyIcon1.Icon = this.Icon;
            //隐藏GH
            ShowWindowAsync(FindWindow(null, "Viz GH Terminal"), SW_HIDE);
            Control.CheckForIllegalCrossThreadCalls = false;
            string temp = confilefile.SelectSingleNode("/root/runvizsleep").InnerText;
            runsleep = int.Parse(temp);
            temp = confilefile.SelectSingleNode("/root/loadscene").InnerText;
            loadscenesleep = int.Parse(temp);
            temp = confilefile.SelectSingleNode("/root/recivesleep").InnerText;
            recivesleep = int.Parse(temp);
            filepath = confilefile.SelectSingleNode("/root/vizpath").InnerText;
            scene = confilefile.SelectSingleNode("/root/scenename").InnerText;
            FrontSceneName = confilefile.SelectSingleNode("/root/FrontSceneName").InnerText;
            ghpath = confilefile.SelectSingleNode("/root/ghpath").InnerText;
            usbserverip = confilefile.SelectSingleNode("/root/usbserverip").InnerText;
            usbsharedport = confilefile.SelectSingleNode("/root/usbsharedport").InnerText;

            processReturnFromCmdEvent = ProcessReturnFromCmdMethod;

            //serverTest = new ServerTest();
            //创建服务端
            process = new NetProcess();
            process.ReciveCommand += new recivecommand(ProcessCommand);
            process.Start();

            pro = new Process();
            pro.StartInfo.UseShellExecute = false;
            pro.StartInfo.FileName = @"cmd.exe";
            pro.StartInfo.WorkingDirectory = @"C:\Windows\System32";//C:\Program Files\USB over Network
            pro.StartInfo.RedirectStandardError = true;
            pro.StartInfo.RedirectStandardInput = true;//可能接受来自调用程序的输入信息 
            pro.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息 
            pro.StartInfo.CreateNoWindow = true;

        }



        string str = "";
        private void OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            str += (e.Data);
           // Console.WriteLine("接收到的数据:.." + e.Data);
          // processReturnFromCmdEvent(e.Data);
        }
        private void StartWin32Cmd()
        {
            backworkPro = new Process();
            backworkPro.StartInfo.UseShellExecute = false;
            backworkPro.StartInfo.RedirectStandardError = true;
            backworkPro.StartInfo.RedirectStandardInput = true;
            backworkPro.StartInfo.RedirectStandardOutput = true;
            backworkPro.StartInfo.CreateNoWindow = true;
            backworkPro.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(OutputDataReceived);
            try
            {
                backworkPro.StartInfo.FileName = @"cmd.exe";
                backworkPro.StartInfo.WorkingDirectory = @"C:\Windows\System32";
                backworkPro.Start();
                backworkPro.StandardInput.WriteLine(@"cd C:\Program Files\USB over Network");
                //发送 显示列表 命令     
                SendMessageToWin32CmdInPathUsb("usbclncmd list -a");
                backworkPro.BeginOutputReadLine();
            }
            catch 
            {

            }
        }
        private void ProcessCommand(string msg)
        {
            string[] arr = msg.Split('*');
            switch (arr[0])
            {
                case "runusbclient":
                    StartUsbClient();
                    break;

                case "closeusbclient":
                    CloseUsbClient();
                    break;

                case "runViz":
                    StartUsbClient();
                    System.Threading.Thread.Sleep(1000);
                    StartWin32Cmd();
                    Thread.Sleep(5000);
                    GetSvrIDAndDevID(str);
                    ConnectUsb();
                    Thread.Sleep(500);
                    backworkPro.Close();
                    str = "";
                    startTimer();
                    StartViz();
                    stopTimer();
                    this.toolStripStatusLabel1.Text = "";
                    break;

                case "disconnect":
                    DisConnectUsb();
                    break;

                case "closeViz":
                    CloseVIZ();
                    break;

                case "reboot":
                    ComputerControl.Reboot();
                    break;

                default:
                    break;
            }

        }

        private void startTimer()
        {
            if (thTimer == null)
            {
                thTimer = new Thread(timer1_Tick);
                thTimer.IsBackground = true;
                thTimer.Start();
            }
            else
            {
                if (!thTimer.IsAlive)
                {
                    thTimer = new Thread(timer1_Tick);
                    thTimer.IsBackground = true;
                    thTimer.Start();
                }
            }

        }
        private void timer1_Tick()
        {
            while (true)
            {
                try
                {
                    bool ret = ShowWindowAsync(FindWindow(null, "Win32 Viz Engine [1] console"), SW_HIDE);//隐藏
                    if (ret)
                    {
                        break;
                    }
                }
                catch { }
                Thread.Sleep(500);
            }
        }

        private void stopTimer()
        {
            try
            {
                thTimer.Abort();
                thTimer = null;
            }
            catch
            { }

        }


        private void ProcessReturnFromCmdMethod(string returnStr)
        {
            if (returnStr.IndexOf("available connections: 0 of 1") > 0)
            {
                Console.WriteLine("该设备已被其他用户占用,请释放再,尝试连接...");
               
                GetSvrIDAndDevID(returnStr);
            }
            else if (returnStr.IndexOf("available connections: 1 of 1") > 0)
            {
                Console.WriteLine("该设备处于空闲状态,可以连接...");
                
                GetSvrIDAndDevID(returnStr);
            }
            else
            {
                
                GetSvrIDAndDevID(returnStr);
            }
        }

        private void SendMessageToWin32CmdInPathUsb(string commandString)
        {
            backworkPro.StandardInput.WriteLine(commandString);
        }

        private void StartUsbClient()
        {
            Process pro = new Process();
            pro.StartInfo.UseShellExecute = true;
            pro.StartInfo.FileName = @"usbclient.exe";
            pro.StartInfo.WorkingDirectory = @"C:\Program Files\USB over Network";
            try
            {
                pro.Start();
            }
            catch (Win32Exception)
            {
            
               // this.Close();
            }
        }

        private void CloseUsbClient()
        {
            Process[] t1 = Process.GetProcessesByName("usbclient");
            if (t1 != null && t1.Length > 0)
                try
                {
                    t1[0].Kill();
                }
                catch { }
        }
        /// <summary>
        /// 关闭Viz GH
        /// 需要关闭三个进程VizDb.exe VizDbTerminal.exe VizDbNamingService.exe
        /// </summary>
        private void CloseGH()
        {
            Process[] t1 = Process.GetProcessesByName("VizDb");
            Process[] t2 = Process.GetProcessesByName("VizDbTerminal");
            Process[] t3 = Process.GetProcessesByName("VizDbNamingService");
            if (t1 != null && t1.Length > 0)
                try
                {
                    t1[0].Kill();
                }
                catch { }
            if (t2 != null && t2.Length > 0)
                try
                {
                    t2[0].Kill();
                }
                catch { }
            if (t3 != null && t3.Length > 0)
                try
                {
                    t3[0].Kill();
                }
                catch { }
        }
        /// <summary>
        /// 
        /// </summary>
        private void StartGH()
        {
            Process pro = new Process();
            pro.StartInfo.UseShellExecute = true;
            pro.StartInfo.FileName = @"VizDbTerminal.exe";
            pro.StartInfo.WorkingDirectory = @ghpath;
            try
            {
                pro.Start();
                System.Threading.Thread.Sleep(5000);
                //ClickPopWindowIsButton();
                ThreadPool.QueueUserWorkItem(new WaitCallback(ClickPopWindowIsButton));
            }
            catch (Win32Exception)
            {
                MessageBox.Show("场景库的路径配置不正确", "启动场景");
                this.Close();
            }
        }
        //关闭程序
        public void Exit()
        {
            this.Close();
        }

        public static int s_HostSrvID = 0;
        public int S_HostSrvID
        {
            get { return s_HostSrvID; }
            set { s_HostSrvID = value; }
        }

        //标示 当前USB主机被占用的 设备号，默认是0
        public static int s_ClientDevID = 0;
        public int S_ClientDevID
        {
            get { return s_ClientDevID; }
            set { s_ClientDevID = value; }
        }

        private void GetSvrIDAndDevID(string returnStr)
        {
            if (returnStr.IndexOf("srvID") >= 0)
            {
              //  int len = 
                string temp = returnStr.Substring(returnStr.IndexOf("srvID:") + 6, returnStr.IndexOf(" ", returnStr.IndexOf("srvID:")) - returnStr.IndexOf("srvID:") - 6);
              //  Console.WriteLine("局域网用户编号:" + temp);
                s_HostSrvID = Int32.Parse(temp);
            }
            if (returnStr.IndexOf("devID:") > 0)
            {
                string temp2 = returnStr.Substring(returnStr.IndexOf("devID:") + 6, returnStr.IndexOf(" ", returnStr.IndexOf("devID:")) - returnStr.IndexOf("devID:") - 6);
             //   Console.WriteLine("局域网主机设备编号:" + temp2);
                s_ClientDevID = Int32.Parse(temp2);
            }
            //if (returnStr.IndexOf("available connections:") > 0)
            //{
            //    string temp3 = returnStr.Substring(11, 19);
            //    //Console.WriteLine("USB设备共享主机地址IP为:" + temp3);
            //}
          //  Console.WriteLine("原始的 [SrvID,DevID]组是:[{0},{1}]", s_HostSrvID, s_ClientDevID);
        }


        private void DisConnectUsb()
        {
            string cmd = string.Format("usbclncmd disconnect {0} {1}", s_HostSrvID, s_ClientDevID);
            try
            {
                pro.Start();
                pro.StandardInput.WriteLine(@"cd C:\Program Files\USB over Network");
                pro.StandardInput.WriteLine(cmd);
            }
            catch
            {
            }
            pro.Close();
        }

        public string ReturnString = "";
        private void ConnectUsb()
        {       
            try
            {
                string cmd = string.Format("usbclncmd connect {0} {1}", s_HostSrvID, s_ClientDevID);
                SendMessageToWin32CmdInPathUsb(cmd);
            }
            catch
            {
            }        
        }


        //启动VIZ
        private void StartViz()
        {
            this.toolStripStatusLabel1.Text = "启动3D引擎中......!";
            CloseVIZ();
            Process pro = new Process();
            pro.StartInfo.UseShellExecute = true;
            pro.StartInfo.FileName = @"viz.cmd";
            pro.StartInfo.Arguments = "-n";
            pro.StartInfo.WorkingDirectory = @filepath;
            try
            {
                pro.Start();
            }
            catch (Win32Exception)
            {
                MessageBox.Show("图形引擎的路径配置不正确", "启动引擎端");
                this.Close();
            }
            ShowWindowAsync(pro.Handle, 0);
            System.Threading.Thread.Sleep(runsleep);
            LoadScene();
        }
        //关闭VIZ程序
        private void CloseVIZ()
        {
            Process[] t1 = Process.GetProcessesByName("VizGui");
            Process[] t2 = Process.GetProcessesByName("viz");
            if (t1 != null && t1.Length > 0)
                try
                {
                    t1[0].Kill();
                }
                catch { }
            if (t2 != null && t2.Length > 0)
                try
                {
                    t2[0].Kill();
                }
                catch { }
        }
        VizEnginePool _pool;
        //载入场景
        public void LoadScene()
        {
            _pool = new VizEnginePool();
            _pool.AddRenderer("127.0.0.1", 6100);
            if (!_pool.Connect())
            {
                MessageBox.Show("未连接到图形引擎", "启动引擎端");
                return;
            }
            this.toolStripStatusLabel1.Text = "开始载入场景...!";
            //增加一个前景场

            _pool.Send("RENDERER*FRONT_LAYER SET_OBJECT " + FrontSceneName + " ;");

            System.Threading.Thread.Sleep(10000);
            _pool.Send("RENDERER*MAIN_LAYER SET_OBJECT " + scene + " ;");

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // ShowWindowAsync(FindWindow(null, "Win32 Viz Engine [1] console"), SW_HIDE);//隐藏
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Confige con = new Confige();
            con.ShowDialog();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F)
            {
                if (!button1.Visible)
                {
                    button1.Visible = true;
                }
                else
                {
                    button1.Visible = false;
                }
            }
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Visible = false;
                this.notifyIcon1.Visible = true;
            }
        }

        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }


        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            this.contextMenuStrip1.Show(MousePosition.X, MousePosition.Y);

        }


        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent,
      IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd,
      int Msg, IntPtr wParam, string lParam);
        const int WM_GETTEXT = 0x000D;
        const int WM_SETTEXT = 0x000C;
        const int WM_CLICK = 0x00F5;

        //关消息的方法
        private void ClickPopWindowIsButton(object obj)
        {
            //这些用spy++可以看到
            string lpszParentClass = "#32770"; //整个窗口的类名
            string lpszParentWindow = "Viz GH Terminal"; //窗口标题
            string lpszClass_Submit = "Button"; //需要查找的Button的类名
            string lpszName_Submit = "Start"; //需要查找的Button的标题          

            IntPtr ParenthWnd = new IntPtr(0);
            IntPtr EdithWnd = new IntPtr(0);
            int i = 0;
            while (true)
            {
                //查到窗体，得到整个窗体
                ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);
                //判断这个窗体是否有效
                if (!ParenthWnd.Equals(IntPtr.Zero))
                {

                    //得到第一级子窗口
                    EdithWnd = FindWindowEx(ParenthWnd,
                        new IntPtr(0), "#32770", "");
                    //Console.WriteLine("第一级-"+EdithWnd.ToString());
                    //得到Button这个子窗体，并触发它的Click事件
                    EdithWnd = FindWindowEx(EdithWnd,
                        new IntPtr(0), lpszClass_Submit, lpszName_Submit);
                    //Console.WriteLine("第二级-" + EdithWnd.ToString());
                    if (!EdithWnd.Equals(IntPtr.Zero))
                    {
                        SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                    }
                    return;
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //ConnectUsb();
            ProcessCommand("runViz");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            StartUsbClient();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            DisConnectUsb();
        }


    }
}
